package com.jg.visitor.config.autoconfiguration.caffeinecache.autoconfig;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.jg.visitor.config.autoconfiguration.caffeinecache.bean.CacheBean;
import com.jg.visitor.config.autoconfiguration.caffeinecache.bean.CacheProperties;
import com.jg.visitor.config.autoconfiguration.caffeinecache.service.CacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Caffeine做缓存自动配置
 * @author cqj
 */
@Slf4j
@Configuration
@EnableCaching
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnProperty(value = "spring.cache.type", havingValue = "caffeine")
public class CaffeineCacheAutoConfiguration {

    @Resource
    private CacheProperties cacheProperties;

    @Bean
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();

        //取缓存配置
        List<CacheBean> list = cacheProperties.getCaches();
        log.info("cacheList : " + list.toString());

        //根据缓存配置转为缓存实例
        List<CaffeineCache> caches = list
                .stream()
                .map(cacheBean -> {
                    //有过期时间就设置过期时间
                    if (cacheBean.getExpirationTime() != null && cacheBean.getExpirationTime() > 0) {
                        Cache<Object, Object> cache = Caffeine
                                .newBuilder()
                                .expireAfterWrite(cacheBean.getExpirationTime(), TimeUnit.SECONDS)
                                .build();
                        return new CaffeineCache(cacheBean.getName(), cache);
                    }
                    //没有就设置普通的缓存
                    return new CaffeineCache(cacheBean.getName(), Caffeine.newBuilder().build());
                })
                .collect(Collectors.toList());
        //设置缓存
        cacheManager.setCaches(caches);

        return cacheManager;
    }

    @Bean
    public CacheService cacheService() {
        return new CacheService();
    }
}
